<template>
  <div class="modal-overlay" v-if="visible" @click="handleCloseOverlay">
    <div class="modal-container" @click.stop>
      <div class="modal">
        <!-- 模态框头部 -->
        <div class="modal-header">
          <h1 class="modal-title">学员档案批量上传</h1>
          <button class="close-btn" @click="handleClose" aria-label="关闭" :disabled="isUploading">×</button>
        </div>

        <!-- 模态框身体 -->
        <div class="modal-body">
          <!-- 待上传学员列表 -->
          <div class="student-table-wrap" v-if="students.length">
            <h3 class="section-title">待上传学员档案需求</h3>
            <table class="student-table">
              <thead>
                <tr>
                  <th width="20%">学员姓名</th>
                  <th width="80%">需上传档案清单</th>
                </tr>
              </thead>
              <tbody>
                <tr v-for="student in students" :key="student.id">
                  <td>{{ student.name }}</td>
                  <td>{{ student.requirements.length ? student.requirements.join('、') : '无特定需求' }}</td>
                </tr>
              </tbody>
            </table>
          </div>
          <div class="empty-student" v-else>
            <i class="el-icon-info"></i> 暂无待上传档案的学员
          </div>

          <!-- 上传规则提示 -->
          <div class="upload-rule">
            <i class="el-icon-warning"></i>
            <div class="rule-text">
              <p>1. 请将每位学员的档案放入单独文件夹，文件夹以「学员姓名」命名（如：张三）</p>
              <p>2. 支持格式：jpg/jpeg/png（单文件≤12MB）、zip/rar（单文件≤50MB）</p>
              <p>3. 文件名建议：身份证正面.jpg、报名表1.png（避免含英文逗号）</p>
            </div>
          </div>

          <!-- 上传控制区域（整合FileUpload子组件） -->
          <div class="upload-control">
            <div class="control-label">选择档案根文件夹：</div>

            <!-- 调用子组件的文件夹选择功能 -->
            <button
              class="btn select-btn"
              @click="triggerFolderSelect"
              :disabled="isUploading || !students.length || !isUploadComponentReady"
            >
              <i class="el-icon-folder-opened" v-if="!isUploading"></i>
              <i class="el-icon-loading el-icon--right" v-if="isUploading"></i>
              {{ isUploading ? '上传中...' : (isUploadComponentReady ? '选择文件夹' : '上传组件加载中...') }}
            </button>

            <!-- 上传组件未就绪提示 -->
            <div class="upload-component-not-ready" v-if="!isUploadComponentReady && !isUploading && students.length">
              <i class="el-icon-info"></i> 上传组件正在准备中，请稍候...
            </div>

            <!-- 进度展示（从子组件接收状态） -->
            <div class="progress-wrap" :class="{ hidden: !selectedFolderInfo }">
              <div class="progress-info">
                <span class="folder-name">当前文件夹：{{ selectedFolderInfo!=null ?selectedFolderInfo.name:'无' }}</span>
                <span class="file-count">进度：{{ uploadedCount }}/{{ selectedFolderInfo!=null ?selectedFolderInfo.validFileCount:'0' }} 个文件</span>
              </div>
              <div class="progress-bar">
                <div
                  class="progress-fill"
                  :style="{ width: totalProgress + '%', backgroundColor: progressColor }"
                ></div>
              </div>
              <div class="progress-percent">{{ totalProgress }}%</div>
              <button
                class="btn cancel-btn"
                @click="cancelUpload"
                :disabled="!isUploading"
              >
                取消上传
              </button>
            </div>
          </div>

          <!-- 错误提示 -->
          <div class="error-tip" v-if="errorMsg">
            <i class="el-icon-error"></i> {{ errorMsg }}
          </div>

          <!-- 上传结果展示 -->
          <div class="upload-result" :class="{ hidden: !uploadFinish }">
            <div class="result-icon" :class="uploadSuccess ? 'success' : 'fail'">
              <i class="el-icon-check" v-if="uploadSuccess"></i>
              <i class="el-icon-error" v-else></i>
            </div>
            <div class="result-text">
              {{ uploadSuccess ?
                `文件夹「${selectedFolderInfo!==null?selectedFolderInfo.name:"无"}」上传完成！共成功${uploadedCount}个文件` :
                `上传失败！共成功${uploadedCount}个，失败${failedCount}个文件`
              }}
            </div>
            <button
              class="btn retry-btn"
              @click="retryUpload"
              :disabled="uploadSuccess || !isUploadComponentReady || isUploading"
            >
              重新上传
            </button>
          </div>

          <!-- 文件夹上传子组件（核心） -->
          <file-upload
            ref="fileUploadRef"
            :action="ruoyiUploadAction"
            :data="uploadData"
            :file-size="fileSizeLimit"
            :file-type="supportFileTypes"
            :limit="Infinity"
            :is-show-tip="false"
            :disabled="isUploading"
            @initialized="handleUploadComponentInitialized"
            @upload-start="handleUploadStart"
            @upload-success="handleUploadSuccess"
            @upload-error="handleUploadError"
            @upload-progress="handleUploadProgress"
            @upload-finish="handleUploadFinish"
            @upload-cancel="handleUploadCancel"
            @folder-selected="handleFolderSelected"
          />
           <!-- 上传方式选择 -->
          <div class="upload-mode">
            <span class="mode-label">上传方式</span>
            <label class="radio">
              <input
                type="radio"
                name="mode"
                value="0"
                v-model="localMode"
                :disabled="isUploading"
              >
              覆盖
            </label>
            <label class="radio">
              <input
                type="radio"
                name="mode"
                value="1"
                v-model="localMode"
                :disabled="isUploading"
              >
              补充
            </label>
          </div>
        </div>

        <!-- 模态框底部 -->
        <div class="modal-footer">
          <button
            class="btn cancel-btn"
            @click="handleClose"
            :disabled="isUploading"
          >
            关闭
          </button>
          <button
            class="btn confirm-btn"
            @click="handleConfirm"
            :disabled="!uploadFinish || isUploading || !uploadSuccess"
          >
            确认完成
          </button>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import FileUpload from "./FileUpload.vue";
import { Message } from "element-ui";

export default {
  name: "FileUploadModal",
  components: { FileUpload },
  props: {
    visible: { type: Boolean, required: true, default: false },
    students: {
      type: Array,
      required: false,
      default: () => [],
      validator: (val) => val.every(item => item.id && item.name && Array.isArray(item.requirements))
    },
    businessId: { type: [String, Number], required: false, default: "" },
    defaultMode: {
      type: String,
      required: false,
      default: "0",
      validator: (val) => ["0", "1"].includes(val)
    }
  },
  data() {
    return {
      localMode: this.defaultMode,
      isUploadComponentReady: false, // 上传组件是否就绪
      isUploading: false, // 是否正在上传
      totalProgress: 0, // 总进度（%）
      uploadedCount: 0, // 上传成功数量
      failedCount: 0, // 上传失败数量
      errorMsg: "", // 错误信息
      uploadFinish: false, // 是否上传完成
      uploadSuccess: false, // 是否全部上传成功
      selectedFolderInfo: null, // 选中的文件夹信息
      loadingInstance: null // 加载提示实例
    };
  },
  computed: {
    // 支持的文件类型（与子组件一致）
    supportFileTypes() {
      return ["jpg", "jpeg", "png", "zip", "rar", "doc", "docx","pdf"];
    },
    // 普通文件大小限制（MB）
    fileSizeLimit() {
      return 12;
    },
    // 上传接口地址
    ruoyiUploadAction() {
      return "/file/upload"; // 与子组件默认action一致，可根据需求修改
    },
    // 上传额外参数（传递给子组件）
    uploadData() {
      return {
        uploadMode: this.localMode,
        businessId: this.businessId,
        targetStudents: JSON.stringify(this.students.map(s => s.name))
      };
    },
    // 进度条颜色（根据进度变化）
    progressColor() {
      if (this.totalProgress < 30) return "#409eff";
      if (this.totalProgress < 70) return "#67c23a";
      return "#1989fa";
    }
  },
  watch: {
    // 监听模态框显示/隐藏
    visible(newVal) {
      if (newVal) {
        // 显示时检查组件状态
        this.checkUploadComponentStatus();
      } else {
        // 隐藏时重置状态
        this.resetAllState();
      }
    },
    // 监听上传模式变化
    defaultMode(newVal) {
      this.localMode = newVal;
      // 同步到子组件
      const fileUpload = this.$refs.fileUploadRef;
      if (fileUpload) fileUpload.data = this.uploadData;
    }
  },
  methods: {
    // 触发子组件的文件夹选择
    triggerFolderSelect() {
      const fileUpload = this.$refs.fileUploadRef;
      if (fileUpload) fileUpload.selectFolder();
    },

    // 处理子组件初始化完成
    handleUploadComponentInitialized() {
      this.isUploadComponentReady = true;
      this.errorMsg = "";
      console.log("上传组件初始化完成");
    },

    // 处理文件夹选择（子组件事件）
    handleFolderSelected(folderInfo) {
      this.selectedFolderInfo = folderInfo;
      this.errorMsg = "";
      // 显示无效文件提示
      if (folderInfo.invalidCount > 0) {
        this.errorMsg = `文件夹中包含${folderInfo.invalidCount}个无效文件（已自动过滤）`;
      }
    },

    // 处理上传开始（子组件事件）
    handleUploadStart(totalCount) {
      this.isUploading = true;
      this.uploadFinish = false;
      this.uploadSuccess = false;
      this.errorMsg = "";
      this.totalProgress = 0;
      this.uploadedCount = 0;
      this.failedCount = 0;

      // 显示加载提示
      this.loadingInstance = Message({
        message: `正在上传${totalCount}个文件，请稍候...`,
        type: "info",
        duration: 0,
        showClose: false
      });
    },

    // 处理单个文件上传成功（子组件事件）
    handleUploadSuccess(file, res) {
      this.uploadedCount++;
      console.log(`文件上传成功：${file.relativePath}`, res);
    },

    // 处理单个文件上传失败（子组件事件）
    handleUploadError(error, file) {
      this.failedCount++;
      const fileName = file ? file.relativePath || file.name : "未知文件";
      this.errorMsg = `文件「${fileName}」上传失败：${error.message}`;
      console.error(`文件上传失败：${fileName}`, error);
    },

    // 处理上传进度更新（子组件事件）
    handleUploadProgress(progress, stats) {
      this.totalProgress = progress;
      this.uploadedCount = stats.uploaded;
      this.failedCount = stats.failed;
    },

    // 处理所有上传完成（子组件事件）
    handleUploadFinish(result) {
      this.isUploading = false;
      this.uploadFinish = true;
      this.uploadedCount = result.uploadedCount;
      this.failedCount = result.failedCount;
      this.uploadSuccess = result.failedCount === 0;
      this.selectedFolderInfo = result.folderInfo;

      // 关闭加载提示
      this.closeLoading();

      // 显示结果提示
      if (this.uploadSuccess) {
        Message.success(`上传完成！共成功${this.uploadedCount}个文件`);
      } else {
        Message.warning(`上传完成！成功${this.uploadedCount}个，失败${this.failedCount}个`);
      }
    },

    // 处理上传取消（子组件事件）
    handleUploadCancel(result) {
      this.isUploading = false;
      this.uploadFinish = true;
      this.uploadSuccess = false;
      this.uploadedCount = result.uploadedCount;
      this.failedCount = result.failedCount;
      this.errorMsg = "上传已手动取消";

      // 关闭加载提示
      this.closeLoading();
      Message.info("上传已取消");
    },

    // 取消上传
    cancelUpload() {
      const fileUpload = this.$refs.fileUploadRef;
      if (fileUpload) fileUpload.cancelUpload();
    },

    // 重新上传
    retryUpload() {
      this.resetUploadState();
      this.triggerFolderSelect();
    },

    // 检查上传组件状态（防止初始化延迟）
    checkUploadComponentStatus() {
      const fileUpload = this.$refs.fileUploadRef;
      if (!fileUpload) return;

      // 立即检查
      if (fileUpload.$el) {
        this.isUploadComponentReady = true;
        return;
      }

      // 延迟重试（最多5次）
      let retryCount = 0;
      const checkTimer = setInterval(() => {
        if (retryCount >= 5 || fileUpload.$el) {
          clearInterval(checkTimer);
          this.isUploadComponentReady = !!fileUpload.$el;
          if (!this.isUploadComponentReady) {
            this.errorMsg = "上传组件加载失败，请刷新页面重试";
          }
          return;
        }
        retryCount++;
      }, 500);
    },

    // 重置上传相关状态
    resetUploadState() {
      this.isUploading = false;
      this.uploadFinish = false;
      this.uploadSuccess = false;
      this.totalProgress = 0;
      this.uploadedCount = 0;
      this.failedCount = 0;
      this.errorMsg = "";

      // 通知子组件重置
      const fileUpload = this.$refs.fileUploadRef;
      if (fileUpload) fileUpload.resetUploadState();
    },

    // 重置所有状态（包括文件夹信息）
    resetAllState() {
      this.resetUploadState();
      this.selectedFolderInfo = null;
      this.isUploadComponentReady = false;

      // 清空子组件文件列表
      const fileUpload = this.$refs.fileUploadRef;
      if (fileUpload) fileUpload.clearFiles();

      // 关闭加载提示
      this.closeLoading();
    },

    // 关闭加载提示
    closeLoading() {
      if (this.loadingInstance) {
        this.loadingInstance.close();
        this.loadingInstance = null;
      }
    },

    // 关闭模态框
    handleClose() {
      this.$emit("update:visible", false);
      this.$emit("close");
      this.resetAllState();
    },

    // 点击遮罩层关闭
    handleCloseOverlay() {
      if (!this.isUploading) this.handleClose();
    },

    // 确认完成上传（向父组件传递结果）
    handleConfirm() {
      const fileUpload = this.$refs.fileUploadRef;
      const fileList = fileUpload ? fileUpload.fileList : [];
      const filePaths = fileList.map(file => file.url); // 已上传文件的URL列表
      const fileDetails = fileList.map(file => ({ // 详细文件信息
        name: file.name,
        url: file.url,
        relativePath: file.relativePath,
        size: file.size,
        ext: file.ext
      }));

      // 向父组件发射确认事件
      this.$emit("confirm", {
        folderName: this.selectedFolderInfo?.name,
        uploadedCount: this.uploadedCount,
        totalFileCount: this.selectedFolderInfo?.totalFileCount || 0,
        filePaths, // 简化的URL列表
        fileDetails, // 详细文件信息
        uploadMode: this.localMode,
        businessId: this.businessId,
        targetStudents: this.students
      });

      // 关闭模态框
      this.handleClose();
    },

    // 检查上传组件状态（重试逻辑）
    checkUploadComponentStatus() {
      const fileUpload = this.$refs.fileUploadRef;
      if (!fileUpload) {
        this.errorMsg = "上传组件未找到";
        return;
      }

      // 立即检查
      if (fileUpload.isUploadComponentReady) {
        this.isUploadComponentReady = true;
        return;
      }

      // 定期重试（最多10次，5秒）
      let checkCount = 0;
      const timer = setInterval(() => {
        if (checkCount >= 10) {
          clearInterval(timer);
          this.isUploadComponentReady = false;
          this.errorMsg = "上传组件加载超时，请刷新页面";
          // 尝试重新初始化子组件
          fileUpload.$emit("initialized");
          return;
        }

        if (fileUpload.$el) {
          clearInterval(timer);
          this.isUploadComponentReady = true;
          this.errorMsg = "";
        }

        checkCount++;
      }, 500);
    }
  },
  // 组件销毁前清理
  beforeDestroy() {
    this.resetAllState();
    this.closeLoading();
  }
};
</script>

<style scoped lang="scss">
/* 模态框遮罩层 */
.modal-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
  //padding: 20px;
  box-sizing: border-box;
}

/* 模态框容器 */
.modal-container {
  width: 100%;
  max-width: 1000px;
  background-color: #fff;
  border-radius: 8px;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
  overflow: hidden;
}

/* 模态框头部 */
.modal-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px 24px;
  background-color: #f5f7fa;
  border-bottom: 1px solid #e0e0e0;
}

.modal-title {
  margin: 0;
  font-size: 18px;
  font-weight: 600;
  color: #1f2329;
}

.close-btn {
  background: none;
  border: none;
  font-size: 22px;
  cursor: pointer;
  color: #86909c;
  padding: 0 8px;
  transition: color 0.2s;

  &:hover:not(:disabled) {
    color: #1f2329;
  }

  &:disabled {
    color: #c0c4cc;
    cursor: not-allowed;
  }
}

/* 模态框身体 */
.modal-body {
  padding: 24px;
  max-height: 60vh;
  overflow-y: auto;
  box-sizing: border-box;
}

/* 学员表格区域 */
.student-table-wrap {
  margin-bottom: 20px;
}

.section-title {
  margin: 0 0 12px;
  font-size: 16px;
  font-weight: 500;
  color: #4e5969;
}

.student-table {
  width: 100%;
  border-collapse: collapse;
  border: 1px solid #e5e6eb;
  border-radius: 4px;
  overflow: hidden;
}

.student-table th,
.student-table td {
  padding: 12px 16px;
  text-align: left;
  border-bottom: 1px solid #e5e6eb;
}

.student-table th {
  background-color: #f7f8fa;
  font-weight: 600;
  color: #4e5969;
}

.student-table tr:last-child td {
  border-bottom: none;
}

.student-table tr:hover td {
  background-color: #f7f8fa;
  transition: background-color 0.2s;
}

/* 无学员提示 */
.empty-student {
  margin-bottom: 20px;
  padding: 20px;
  border: 1px dashed #e5e6eb;
  border-radius: 4px;
  color: #86909c;
  text-align: center;
  background-color: #f7f8fa;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}

/* 上传规则提示 */
.upload-rule {
  margin-bottom: 24px;
  padding: 12px 16px;
  background-color: #f8f9fa;
  border-left: 4px solid #409eff;
  border-radius: 4px;
  display: flex;
  gap: 12px;
  align-items: flex-start;
}

.upload-rule .el-icon-warning {
  color: #409eff;
  font-size: 18px;
  margin-top: 2px;
}

.rule-text {
  flex: 1;
  font-size: 14px;
  color: #666;
  line-height: 1.6;
}

.rule-text p {
  margin: 0 0 8px;
}

.rule-text p:last-child {
  margin-bottom: 0;
}

/* 上传控制区域 */
.upload-control {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 16px;
  margin-bottom: 16px;
}

.control-label {
  font-size: 14px;
  color: #4e5969;
  font-weight: 500;
  min-width: 120px;
}

/* 通用按钮样式 */
.btn {
  padding: 8px 16px;
  border-radius: 4px;
  border: none;
  cursor: pointer;
  font-size: 14px;
  transition: all 0.2s;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}

/* 选择文件夹按钮 */
.select-btn {
  background-color: #409eff;
  color: #fff;

  &:hover:not(:disabled) {
    background-color: #3688e6;
  }

  &:disabled {
    background-color: #a0cfff;
    cursor: not-allowed;
    color: #fff;
  }
}

/* 上传组件未就绪提示 */
.upload-component-not-ready {
  width: 100%;
  margin-top: 8px;
  padding: 8px 12px;
  background-color: #f8f9fa;
  border-radius: 4px;
  font-size: 13px;
  color: #86909c;
  display: flex;
  align-items: center;
  gap: 6px;
}

/* 进度展示区域 */
.progress-wrap {
  width: 100%;
  margin-top: 8px;
  padding: 12px 16px;
  background-color: #f7f8fa;
  border-radius: 4px;
  box-sizing: border-box;
}

.progress-wrap.hidden {
  display: none;
}

.progress-info {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  margin-bottom: 8px;
  font-size: 14px;
  color: #4e5969;
}

.folder-name {
  font-weight: 500;
}

/* 进度条样式 */
.progress-bar {
  width: 100%;
  height: 8px;
  background-color: #e5e6eb;
  border-radius: 4px;
  overflow: hidden;
}

.progress-fill {
  height: 100%;
  transition: width 0.3s ease;
}

/* 进度百分比 */
.progress-percent {
  margin-top: 8px;
  font-size: 14px;
  color: #86909c;
  text-align: right;
}

/* 取消按钮 */
.cancel-btn {
  background-color: #f56c6c;
  color: #fff;
  margin-top: 8px;

  &:hover:not(:disabled) {
    background-color: #e64949;
  }

  &:disabled {
    background-color: #fab6b6;
    cursor: not-allowed;
  }
}

/* 错误提示 */
.error-tip {
  margin-bottom: 16px;
  padding: 12px 16px;
  background-color: #fef0f0;
  border-radius: 4px;
  color: #f56c6c;
  font-size: 14px;
  display: flex;
  align-items: center;
  gap: 8px;
}

/* 上传结果展示 */
.upload-result {
  margin-top: 16px;
  padding: 16px;
  background-color: #f7f8fa;
  border-radius: 4px;
  display: flex;
  align-items: center;
  gap: 16px;
}

.upload-result.hidden {
  display: none;
}

/* 结果图标 */
.result-icon {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
}

.result-icon.success {
  background-color: #f0f9eb;
  color: #67c23a;
}

.result-icon.fail {
  background-color: #fef0f0;
  color: #f56c6c;
}

.result-text {
  flex: 1;
  font-size: 14px;
  color: #4e5969;
}

/* 重试按钮 */
.retry-btn {
  background-color: #409eff;
  color: #fff;

  &:hover:not(:disabled) {
    background-color: #3688e6;
  }

  &:disabled {
    background-color: #a0cfff;
    cursor: not-allowed;
  }
}

/* 模态框底部 */
.modal-footer {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
  padding: 16px 24px;
  border-top: 1px solid #e0e0e0;
  background-color: #f5f7fa;
}

/* 底部关闭按钮 */
.modal-footer .cancel-btn {
  background-color: #fff;
  color: #4e5969;
  border: 1px solid #e5e6eb;
  margin-top: 0;

  &:hover:not(:disabled) {
    background-color: #f5f5f5;
  }

  &:disabled {
    background-color: #f5f5f5;
    color: #909399;
    border-color: #e0e0e0;
  }
}

/* 确认完成按钮 */
.confirm-btn {
  background-color: #67c23a;
  color: #fff;

  &:hover:not(:disabled) {
    background-color: #52c41a;
  }

  &:disabled {
    background-color: #b7eb8f;
    cursor: not-allowed;
  }
}

/* 响应式适配（移动端） */
@media (max-width: 768px) {
  .modal-header {
    padding: 12px 16px;
  }

  .modal-title {
    font-size: 16px;
  }

  .modal-body {
    padding: 16px;
    max-height: 50vh;
  }

  .upload-control {
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
  }

  .control-label {
    min-width: auto;
  }

  .progress-info {
    flex-direction: column;
    gap: 8px;
  }

  .modal-footer {
    padding: 12px 16px;
  }
}
</style>
